- App Mcp
App Mcp
<link rel="shortcut icon" href="../../images/UnoLogoSmall.png">
<link rel="stylesheet" href="../../styles/docfx.vendor.min.css">
<link rel="stylesheet" href="../../styles/docfx.css">
<link rel="stylesheet" href="../../styles/main.css">
<meta property="docfx:navrel" content="">
<meta property="docfx:tocrel" content="../toc.html">
<nav class="navbar ng-scope" id="header-container" role="navigation">
<div id="header-logo-container">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../images/uno-logo.png" alt="">
</a>
</div>
<button type="button" class="navbar-toggle" id="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="collapse navbar-collapse navbar-expand-lg" id="navbar"></div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
<div id="sdk-version-info">
<span class="sdk-version-badge" title="Latest stable Uno SDK version" role="button" tabindex="0" onkeydown="if (event.key === 'Enter') { event.preventDefault(); this.click(); } else if (event.key === ' ') { event.preventDefault(); }" onkeyup="if (event.key === ' ') { this.click(); }">
<span class="sdk-label">SDK</span>
<span class="sdk-version">Loading...</span>
</span>
</div>
</header>
<div role="main" class="container body-content">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-8">
<article class="content wrap" id="_content" data-uid="Uno.Features.Uno.MCPs">
The Uno Platform MCPs
Uno Platform provides two MCPs:
- The Uno Platform Remote MCP, providing prompts and up-to-date documentation
- The Uno Platform Local App MCP, providing interactive access to your running application
This document explains how to interact with both those MCPs. You can find further below descriptions of the provided tools and prompts.
MCP (Remote)
This is a remotely hosted publicly and provides:
- A set of tools to search and fetch Uno Platform documentation
- A set of prompts to create and develop Uno Platform applications.
Predefined Prompts
The prompts provided by the MCP are automatically registered in your environment when supported by your AI agent (e.g., Claude, Codex, Copilot, etc.).
Here are the currently supported prompts:
/new, used to create a new Uno Platform app with the best practices in mind./init, used to "prime" your current chat with Uno's best practices. It's generally used in an existing app when adding new features.
Sample Prompts for Uno MCP Servers
You can find common prompts to use with agents in our getting started section.
Uno MCP Tools
The Uno MCP tools are the following:
uno_platform_docs_searchused by Agents to search for specific topics. It returns snippets of relevant information.uno_platform_docs_fetchused by Agents to get a specific document, grabbed throughuno_platform_docs_search.uno_platform_agent_rules_initused by Agents to "prime" the environment on how to interact with Uno Platform apps during development.uno_platform_usage_rules_initused by Agents to "prime" the environment on how to Uno Platform's APIs in the best way possible
Those tools are suggested to the agent on how to be used best. In general, asking the agent "Make sure to search the Uno Platform docs to answer" will hint it to use those tools.
Note
You can unselect uno_platform_agent_rules_init and uno_platform_usage_rules_init in your agent to avoid implicit priming, and you can use the /init prompt to achieve a similar result.
App MCP (Local)
This MCP is running locally and provides agents with the ability to interact with a running app, in order to click, type, analyze or screenshot its content.
These tools give "eyes" and "hands" to Agents in order to validate their assumptions regarding the actions they take, and the code they generate.
Note
If using Visual Studio 2022/2026, sometimes the Uno App MCP does not appear in the Visual Studio tools list. See how to make the App MCP appear in Visual Studio.
App MCP Tools
The Community license MCP app tools are:
uno_app_get_runtime_info, used to get general information about the running app, such as its PID, OS, Platform, etc...uno_app_get_screenshot, used to get a screenshot of the running appuno_app_pointer_click, used to click at an X,Y coordinates in the appuno_app_key_press, used to type individual keys (possibly with modifiers)uno_app_type_text, used to type long strings of text in controlsuno_app_visualtree_snapshot, used to get a textual representation of the visual tree of the appuno_app_element_peer_default_action, used to execute the default automation peer action on a UI elementuno_app_close, used to close the running app
The Pro license App MCP app tools are:
uno_app_element_peer_action, used to invoke a specific element automation peer actionuno_app_get_element_datacontext, used to get a textual representation of the DataContext on a FrameworkElement
Troubleshooting MCP Servers
You can find additional information about troubleshooting AI Agents in our docs.
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
<li>
<a href="https://github.com/unoplatform/uno/blob/master/doc/articles/features/using-the-uno-mcps.md/#L1" class="contribution-link">Edit this page</a>
</li>
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<h5>In this article</h5>
<div></div>
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<!-- Mermaid -->
<!-- Lets you create diagrams and visualizations using text and code. -->
<script type="text/javascript" src="../../styles/docfx.vendor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/highlight.min.js"></script>
<script src="https://unpkg.com/highlightjs-dotnetconfig@0.9.3/dist/dotnetconfig.min.js"></script>
<script type="text/javascript" src="../../styles/docfx.js"></script>
<script type="text/javascript" src="../../styles/main.js"></script>
<!-- Mermaid version will need to be bumped here when this issue is fixed -->
<!-- Search for this issue in the code to remove the related workaround: https://github.com/mermaid-js/mermaid/issues/1984 -->
<script type="text/javascript" src="https://unpkg.com/mermaid@8.14.0/dist/mermaid.min.js" integrity="sha384-atOyb0FxAgN9LyAc6PEf9BjgwLISyansgdH8/VXQH8p2o5vfrRgmGIJ2Sg22L0A0" crossorigin="anonymous"></script>
<script>
mermaid.initialize({
startOnLoad: false
});
mermaid.init(undefined, ".lang-mermaid");
</script>
<!-- Algolia DocSearch -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@3"></script>
<script>
/**
* Initialize Algolia DocSearch
* This function initializes DocSearch for the element with id 'docsearch'.
*/
function initializeDocSearch() {
console.log("initializeDocSearch called");
try {
const searchBox = document.getElementById("docsearch");
if (searchBox) {
console.log("Found 'docsearch' element");
// Check if the search box is already initialized
if (searchBox.children.length > 0) {
console.log("Search box already initialized.");
// Disconnect the observer if search box is already initialized
if (observer) {
observer.disconnect();
console.log("MutationObserver disconnected.");
}
} else {
// Initialize DocSearch if not already initialized
console.log("Initializing DocSearch...");
docsearch({
container: '#docsearch',
appId: 'PHB9D8WS99',
indexName: 'platform',
apiKey: '7877394996f96cde1a9b795dce3f7787',
placeholder: 'Search Docs...'
});
console.log("DocSearch initialized.");
// Disconnect the observer after initialization
if (observer) {
observer.disconnect();
console.log("MutationObserver disconnected.");
}
}
} else {
console.warn("'docsearch' element not found.");
}
} catch (error) {
console.error("Error initializing DocSearch:", error);
}
}
/**
* Set up MutationObserver to watch for additions to the DOM
* This function sets up a MutationObserver to monitor the entire document for added nodes.
* If the 'docsearch' element is added, it will call initializeDocSearch().
*/
let observer;
function observeDocSearch() {
observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
mutation.addedNodes.forEach((node) => {
// Check if the added node is the 'docsearch' element
if (node.id === 'docsearch') {
console.log("'docsearch' element added to DOM");
initializeDocSearch();
}
});
}
});
});
// Observe the entire document for child additions
observer.observe(document.body, {
childList: true,
subtree: true
});
console.log("MutationObserver set up to observe 'docsearch' element");
}
/**
* Retry initialization using requestAnimationFrame
* This function tries to initialize DocSearch using requestAnimationFrame for better timing handling for some browsers like Firefox.
*/
function retryInitialization() {
if (!document.getElementById('docsearch')) {
console.log("Retrying DocSearch initialization using requestAnimationFrame");
requestAnimationFrame(retryInitialization);
} else {
initializeDocSearch();
}
}
/**
* Load event handler
* This function handles the load event to ensure the entire page is fully loaded.
* It then checks if the 'docsearch' element is present and initializes DocSearch.
* If the element is not present, it sets up the MutationObserver and starts the retry mechanism.
*/
window.addEventListener('load', () => {
console.log("Load event fired");
// Check if the 'docsearch' element already exists in the DOM
if (document.getElementById('docsearch')) {
console.log("'docsearch' element already present in DOM");
initializeDocSearch();
} else {
console.log("'docsearch' element not present in DOM, setting up MutationObserver");
observeDocSearch();
// Start retrying using requestAnimationFrame
retryInitialization();
}
});
</script>
<!-- Easy-copy-code -->
<script>
$(function() {
var copyToClipboard = function(text) {
// Create a textblock and assign the text and add to document
var el = document.createElement('textarea');
el.value = text;
document.body.appendChild(el);
el.style.display = "block";
// select the entire textblock
if (window.document.documentMode)
el.setSelectionRange(0, el.value.length);
else
el.select();
// copy to clipboard
document.execCommand('copy');
// clean up element
document.body.removeChild(el);
}
$("code.hljs, code[class^='lang-']").each(function() {
var $this = $(this);
var language = /lang-(.+?)(\s|$)/.exec($this.attr("class"));
if (language === null) {
language = "";
}
else language = language[1].toUpperCase();
// Skip lang-mermaid as we don't need the easy-copy-code for mermaid graphs
if (language === 'MERMAID') {
return;
}
if (language === 'CPP') {
language = "C++";
}
if (language === 'CSHARP' || language === 'CS') {
language = "C#";
}
if (language === 'JS') {
language = "JavaScript";
}
if (language === 'DOTNETCLI') {
language = ".NET CLI";
}
if (language === 'PWSH') {
language = "PowerShell";
}
var $codeHeader = $(
'<div class="code-header">'+
' <span class="language">'+ language +'</span>'+
' <button type="button" class="action" aria-label="Copy code">'+
' <span class="icon"><span class="glyphicon glyphicon-duplicate" role="presentation"></span></span>'+
' <span>Copy</span>'+
' <div class="successful-copy-alert is-transparent" aria-hidden="true">'+
' <span class="icon is-size-large">'+
' <span class="glyphicon glyphicon-ok" role="presentation"></span>'+
' </span>'+
' </div>'+
' </button>'+
'</div>'
);
$this.closest("pre").before($codeHeader);
$codeHeader.find("button").click(function() {
copyToClipboard($this.closest("pre").text());
var successAlert = $(this).find(".successful-copy-alert");
successAlert.removeClass("is-transparent");
setTimeout(function() {successAlert.addClass("is-transparent");}, 2000);
});
});
});
</script>
Server Config
{
"mcpServers": {
"uno-devserver": {
"command": "uno-devserver",
"args": [
"--mcp-app"
]
}
}
}